import pyautogui
import tkinter as tk
from PIL import ImageGrab
import colorsys  # 新增颜色空间转换库


class ColorDetector:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("HSV智能取色器")

        # 初始化时添加快捷键绑定
        self.root.bind('<Control-s>', lambda event: self.set_target_color())
        self.root.bind('<Control-S>', lambda event: self.set_target_color())

        # 状态变量
        self.target_hsv = None  # 改为存储HSV值
        self.h_tolerance = 15  # 色相容差（单位：度）
        self.s_tolerance = 30  # 饱和度容差（单位：%）
        self.v_tolerance = 40  # 明度容差（单位：%）
        self.detecting = False

        # GUI布局
        self.setup_ui()

    def setup_ui(self):
        # 状态显示
        self.status_label = tk.Label(self.root,
                                     text="未选择目标颜色\n(使用 Ctrl+S 快速锁定)",
                                     font=('Arial', 12))
        self.status_label.pack(pady=10)

        # 当前颜色显示
        self.current_frame = tk.Frame(self.root, width=100, height=100, relief="groove")
        self.current_frame.pack(pady=5)

        # 目标颜色显示
        self.target_frame = tk.Frame(self.root, width=100, height=100, relief="groove")
        self.target_frame.pack(pady=5)

        # 控制面板（新增三个容差输入）
        control_frame = tk.Frame(self.root)
        control_frame.pack(pady=10)

        # 色相容差设置
        tk.Label(control_frame, text="色相(°):").grid(row=0, column=0)
        self.h_tol_entry = tk.Entry(control_frame, width=5)
        self.h_tol_entry.insert(0, "15")
        self.h_tol_entry.grid(row=0, column=1, padx=5)

        # 饱和度容差设置
        tk.Label(control_frame, text="饱和度(%):").grid(row=0, column=2)
        self.s_tol_entry = tk.Entry(control_frame, width=5)
        self.s_tol_entry.insert(0, "30")
        self.s_tol_entry.grid(row=0, column=3, padx=5)

        # 明度容差设置
        tk.Label(control_frame, text="明度(%):").grid(row=0, column=4)
        self.v_tol_entry = tk.Entry(control_frame, width=5)
        self.v_tol_entry.insert(0, "40")
        self.v_tol_entry.grid(row=0, column=5, padx=5)

        # 功能按钮
        tk.Button(control_frame, text="锁定颜色 (Ctrl+S)",
                  command=self.set_target_color).grid(row=1, column=0, columnspan=3, pady=5)
        tk.Button(control_frame, text="开始检测",
                  command=self.toggle_detection).grid(row=1, column=3, columnspan=3)

        # 提示信息
        self.info_label = tk.Label(self.root,
                                   text="移动鼠标查看颜色 | Ctrl+S 锁定颜色 | Ctrl+C 退出",
                                   font=('Arial', 10))
        self.info_label.pack(pady=5)

    def rgb_to_hsv(self, rgb):
        """将0-255的RGB转换为0-1范围的HSV"""
        return colorsys.rgb_to_hsv(rgb[0] / 255.0, rgb[1] / 255.0, rgb[2] / 255.0)

    def is_color_in_range(self, current_rgb):
        """HSV颜色匹配核心逻辑"""
        if not self.target_hsv:
            return False

        # 转换当前颜色到HSV
        current_hsv = self.rgb_to_hsv(current_rgb)
        t_h, t_s, t_v = self.target_hsv
        c_h, c_s, c_v = current_hsv

        # 计算色相环差异（单位：度）
        hue_diff = min(abs(t_h - c_h), 1 - abs(t_h - c_h)) * 360

        # 计算饱和度/明度差异（单位：%）
        sat_diff = abs(t_s - c_s) * 100
        val_diff = abs(t_v - c_v) * 100

        # 三重条件判断
        return (hue_diff <= self.h_tolerance and
                sat_diff <= self.s_tolerance and
                val_diff <= self.v_tolerance)

    def set_target_color(self, event=None):
        """设置目标颜色（HSV格式）"""
        try:
            x, y = pyautogui.position()
            screenshot = ImageGrab.grab()
            rgb = screenshot.getpixel((x, y))

            # 更新目标颜色和容差设置
            self.target_hsv = self.rgb_to_hsv(rgb)
            self.h_tolerance = int(self.h_tol_entry.get())
            self.s_tolerance = int(self.s_tol_entry.get())
            self.v_tolerance = int(self.v_tol_entry.get())

            # 更新UI显示
            hex_color = '#{:02x}{:02x}{:02x}'.format(*rgb)
            self.target_frame.config(bg=hex_color)
            status_text = f"目标颜色已锁定 @ ({x}, {y})\n"
            status_text += f"容差: H±{self.h_tolerance}° S±{self.s_tolerance}% V±{self.v_tolerance}%"
            self.status_label.config(text=status_text)

            # 绿色反馈效果
            self.current_frame.config(bg='#4CAF50')
            self.root.after(200, lambda: self.current_frame.config(bg=hex_color))
        except Exception as e:
            self.status_label.config(text=f"锁定失败: {str(e)}")

    def toggle_detection(self):
        """切换检测状态（保持不变）"""
        self.detecting = not self.detecting
        if self.detecting and not self.target_hsv:
            self.status_label.config(text="请先锁定目标颜色！")
            self.detecting = False
            return
        status = "运行中" if self.detecting else "已停止"
        self.status_label.config(text=f"检测状态: {status}")

    def update_color(self):
        try:
            x, y = pyautogui.position()
            screenshot = ImageGrab.grab()
            current_rgb = screenshot.getpixel((x, y))

            # 更新当前颜色显示
            hex_color = '#{:02x}{:02x}{:02x}'.format(*current_rgb)
            self.current_frame.config(bg=hex_color)

            # 颜色检测逻辑
            if self.detecting and self.target_hsv:
                if self.is_color_in_range(current_rgb):
                    self.root.config(bg="green")
                    self.info_label.config(text="★ 检测到目标颜色！ ★")
                else:
                    self.root.config(bg="white")
                    self.info_label.config(text="移动鼠标查看颜色 | Ctrl+C 退出")

            self.root.after(50, self.update_color)
        except Exception as e:
            print(f"错误: {e}")

    def run(self):
        self.root.after(0, self.update_color)
        self.root.mainloop()


if __name__ == "__main__":
    detector = ColorDetector()
    try:
        detector.run()
    except KeyboardInterrupt:
        print("程序已安全退出")